package com.dd.cloud.user.service.admin.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.auth.entity.AdminRole;
import com.dd.cloud.auth.req.role.UserBindRoleReq;
import com.dd.cloud.auth.res.UserToRoleRes;
import com.dd.cloud.common.config.servlet.JwtUtils;
import com.dd.cloud.common.config.sms.SmsComponent;
import com.dd.cloud.common.constants.AdminConstants;
import com.dd.cloud.common.constants.HealthConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.*;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.admin.AdminUser;
import com.dd.cloud.user.feign.AuthFeignService;
import com.dd.cloud.user.mapper.admin.AdminUserMapper;
import com.dd.cloud.user.req.admin.AddAdminUserReq;
import com.dd.cloud.user.req.admin.GetAdminPageReq;
import com.dd.cloud.user.req.admin.StatisticalMechanDateNodeReq;
import com.dd.cloud.user.req.admin.UpdateAdminUserReq;
import com.dd.cloud.user.req.mechan.MechanRankPresStatisticalReq;
import com.dd.cloud.user.req.mechan.MechanRankSelectStatisticalReq;
import com.dd.cloud.user.res.admin.*;
import com.dd.cloud.user.res.mechan.MechanRankPresRes;
import com.dd.cloud.user.res.mechan.MechanRankSelectRes;
import com.dd.cloud.user.service.admin.IAdminUserService;
import com.dd.cloud.user.service.admin.IIpWriteListService;
import com.dd.cloud.user.service.common.ICommonService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 管理员用户 服务实现类
 * </p>
 *
 * @author czg
 * @since 2022-04-27
 */
@Service
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements IAdminUserService {
    @Autowired
    private SmsComponent smsComponent;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private ICommonService commonService;
    @Autowired
    private AuthFeignService authFeignService;
    @Autowired
    private IIpWriteListService ipWriteListService;

    /**
     * 运营管理员用户登录 验证码
     *
     * @param request
     * @param response
     * @param phone
     * @param code
     * @return
     */
    @Override
    public AdminUserRes adminUserLoginCode(HttpServletRequest request, HttpServletResponse response, String phone, String code) {
        if (StringUtils.isBlank(code)) {
            throw new ZekeException(ZkExceptionEnum.INVALID_VERIFY_CODE);
        }
        String ipAddress = IPUtil.getIpAddress(request);
        List<String> list = ipWriteListService.getWriteIp(1);
        if (!list.isEmpty() && !list.contains(ipAddress)){
            throw new ZekeException(400, "管理员限定ip登录");
        }
        //查询账号
        QueryWrapper<AdminUser> q = new QueryWrapper<>();
        q.lambda().eq(AdminUser::getPhone, phone);
        q.lambda().ne(AdminUser::getStatus, AdminConstants.UserStatus.DEL);
        AdminUser user = getOne(q);
        if (user == null) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_NOT_FOUND);
        }
        smsComponent.verifyPhoneCode(phone, code);
//        verifyClient(request, user.getType());
        //校验账号状态
        switch (user.getStatus()) {
            case AdminConstants.UserStatus.DEL:
                throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_DELETED);
            case AdminConstants.UserStatus.DISABLEADMIN:
                throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_FORBIDDEN);
            default:
        }
        LoginInfo loginInfo = new LoginInfo(user.getId(), 0, LoginInfo.UserType.ADMIN, user.getNickName(), 0, jwtUtils.getUserAgent(request));
        try {
            ResponseEntity<AdminRole> entity = authFeignService.roleIdByUserId(loginInfo);
            loginInfo.setRoleId(entity.getBody().getId());
        } catch (Exception e) {
            log.error("授权失败");
            e.printStackTrace();
        }
        jwtUtils.createToken(loginInfo, request, response);
        AdminUserRes res = new AdminUserRes();
        BeanUtils.copyProperties(user, res);
        res.setRoleId(loginInfo.getRoleId());
        return res;
    }

    /**
     * 运营管理员登录
     *
     * @param request
     * @param response
     * @param account
     * @param password
     * @return
     */
    @Override
    public AdminUserRes adminUserLoginPwd(HttpServletRequest request, HttpServletResponse response, String account, String password) {
        //检查密码错误是否超过次数
        commonService.checkLoginPwdError(request, account);
        String ipAddress = IPUtil.getIpAddress(request);
        List<String> list = ipWriteListService.getWriteIp(1);
        if (!list.isEmpty() && !list.contains(ipAddress)){
            throw new ZekeException(400, "管理员限定ip登录");
        }
        //查询账号
        QueryWrapper<AdminUser> q = new QueryWrapper<>();
        q.lambda().eq(AdminUser::getAccount, account);
        q.lambda().ne(AdminUser::getStatus, AdminConstants.UserStatus.DEL);
        AdminUser user = getOne(q);
        if (user == null) {
            throw new ZekeException(ZkExceptionEnum.INVALID_USERNAME_PASSWORD);
        }
//        verifyClient(request, user.getType());
        //校验账号状态
        switch (user.getStatus()) {
            case AdminConstants.UserStatus.DEL:
                throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_DELETED);
            case AdminConstants.UserStatus.DISABLEADMIN:
                throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_FORBIDDEN);
            default:
        }

        //校验密码
        q.lambda().eq(AdminUser::getPassword, CodecUtils.md5Hex(password, user.getSalt()));
        user = getOne(q);
        if (user == null) {
            //增加密码错误次数
            commonService.loginPwdError(request, account);
            throw new ZekeException(ZkExceptionEnum.INVALID_USERNAME_PASSWORD);
        }
        LoginInfo loginInfo = new LoginInfo(user.getId(), 0, LoginInfo.UserType.ADMIN, user.getNickName(), 0, jwtUtils.getUserAgent(request));
        try {
            ResponseEntity<AdminRole> entity = authFeignService.roleIdByUserId(loginInfo);
            loginInfo.setRoleId(entity.getBody().getId());
        } catch (Exception e) {
            log.error("授权失败");
            e.printStackTrace();
        }
        jwtUtils.createToken(loginInfo, request, response);
        //生成token并写入cookie
        //jwtUtils.createToken(new LoginInfo(user.getId(), 0, LoginInfo.UserType.ADMIN, user.getNickName()), request, response);
        AdminUserRes res = new AdminUserRes();
        BeanUtils.copyProperties(user, res);
        res.setRoleId(loginInfo.getRoleId());
        return res;
    }

    /**
     * 验证客户端
     *
     * @param request
     * @param type
     */
    public void verifyClient(HttpServletRequest request, Integer type) {
        String client = request.getHeader("client");
        if (StringUtils.isBlank(client)) {
            throw new ZekeException(400, "未知客户端");
        }
        switch (type) {
            case AdminConstants.UserType.PLAIN:
            case AdminConstants.UserType.ADMIN:
            case AdminConstants.UserType.ZRK:
                if (!client.equals(HealthConstants.ClientType.HEALTHADMIN)) {
                    throw new ZekeException(400, "请使用运营后台客户端登录");
                }
                break;
            case AdminConstants.UserType.SALE:
                if (!client.equals(HealthConstants.ClientType.HEALTHSALES)) {
                    throw new ZekeException(400, "请使用销售后台客户端登录");
                }
            default:
        }
    }

    /**
     * 添加运营管理员
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAdminUser(AddAdminUserReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        AdminUser adminUser = new AdminUser();
        if (checkPhoneUsed(req.getPhone())) {
            throw new ZekeException(ZkExceptionEnum.PHONE_IS_EXISTS);
        }
        if (checkAccountUsed(req.getAccount())) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_EXISTS);
        }

        BeanUtils.copyProperties(req, adminUser);
        if (StringUtils.isBlank(req.getPassword())) {
            // 对密码进行加密
            String salt = CodecUtils.generateSalt();
            adminUser.setSalt(salt);
            adminUser.setPassword(CodecUtils.md5Hex(adminUser.getPhone().substring(adminUser.getPhone().length() - 6), adminUser.getSalt()));
        } else {
            if (!req.getPassword().equals(req.getResPwd())) {
                throw new ZekeException(400, "重复密码不正确");
            }
            // 对密码进行加密
            String salt = CodecUtils.generateSalt();
            adminUser.setSalt(salt);
            adminUser.setPassword(CodecUtils.md5Hex(req.getPassword(), adminUser.getSalt()));
        }
        adminUser.setCreateId(loginInfo.getId());
        adminUser.setCreateName(loginInfo.getName());
        adminUser.setCreateDate(LocalDateTime.now());
        adminUser.setStatus(AdminConstants.UserStatus.NORMAL);
        adminUser.setType(AdminConstants.UserType.PLAIN);
        int i = getBaseMapper().insert(adminUser);
        if (i <= 0) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
        ResponseEntity<Integer> integerResponseEntity = authFeignService.userIsAdmin(adminUser.getId(), LoginInfo.UserType.ADMIN);

        if (integerResponseEntity.getBody() == AdminConstants.Admin.ADMIN) {
            throw new ZekeException("不能添加超级管理员");
        }
        if (req.getRoleId() != null) {
            //adminPowerService.bindUserRole(adminUser.getId(), req.getRoleId(), LoginInfo.UserType.ADMIN);
            authFeignService.userBindRole(new UserBindRoleReq(adminUser.getId(), req.getRoleId(), LoginInfo.UserType.ADMIN, null));

        }
    }

    /**
     * 查询管理员详情
     *
     * @param id
     * @return
     */
    @Override
    public AdminUserDetailRes getAdminUserDetail(Integer id) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        AdminUserDetailRes userDeatil = getBaseMapper().getUserDeatil(id);
        ResponseEntity<AdminRole> entity = authFeignService.queryRoleByUserId(id, LoginInfo.UserType.ADMIN);
        if (entity != null && entity.getBody() != null){
            AdminRole body = entity.getBody();
            userDeatil.setRoleId(body.getId());
            userDeatil.setRoleName(body.getRoleName());
        }
        return userDeatil;
    }

    /**
     * 修改运营管理员
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAdminUser(UpdateAdminUserReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        AdminUser adminUser = getById(req.getId());
        if (adminUser == null) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_NOT_FOUND);
        }
        if (!req.getAccount().equals(adminUser.getAccount())) {
            throw new ZekeException(400, "不能修改登录账号");
        }
        if (!req.getPhone().equals(adminUser.getPhone())) {
            adminUser.setPhone(req.getPhone());
            //修改了手机号
            if (checkPhoneUsed(req.getPhone())) {
                throw new ZekeException(ZkExceptionEnum.PHONE_IS_EXISTS);
            }
        }

        BeanUtils.copyProperties(req, adminUser);
        if (!StringUtils.isBlank(req.getPassword())) {

            if (StringUtils.isBlank(req.getResPwd())
                    || !req.getPassword().equals(req.getResPwd())) {
                throw new ZekeException(400, "重复密码不正确");
            }
            // 对密码进行加密
            String salt = CodecUtils.generateSalt();
            adminUser.setSalt(salt);
            adminUser.setPassword(CodecUtils.md5Hex(req.getPassword(), adminUser.getSalt()));
        }
        ResponseEntity<Integer> integerResponseEntity = authFeignService.userIsAdmin(loginInfo.getId(), LoginInfo.UserType.ADMIN);
        ResponseEntity<Integer> integerResponseEntity2 = authFeignService.userIsAdmin(req.getId(), LoginInfo.UserType.ADMIN);
        int powerLogin = integerResponseEntity.getBody();
        int powerUpdate = integerResponseEntity2.getBody();
        if (powerUpdate != req.getRoleId() && powerLogin != AdminConstants.Admin.ADMIN) {
            throw new ZekeException(400, "您的账号是普通管理员, 不能修改其他管理员的角色");
        }
        if (powerUpdate == AdminConstants.Admin.ADMIN) {
            throw new ZekeException(400, "不能修改超级管理员");
        }
        boolean i = updateById(adminUser);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
        if (req.getRoleId() != null) {
            authFeignService.userBindRole(new UserBindRoleReq(req.getId(), req.getRoleId(), LoginInfo.UserType.ADMIN, null));
            //adminPowerService.bindUserRole(adminUser.getId(), req.getRoleId(), LoginInfo.UserType.ADMIN);
        }
    }

    /**
     * 修改管理员状态
     *
     * @param id
     * @param status
     */
    @Override
    public void updateAdminUserStatus(Integer id, Integer status) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();
        AdminUser adminUser = getById(id);
        if (adminUser == null) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_NOT_FOUND);
        }
        ResponseEntity<Integer> integerResponseEntity = authFeignService.userIsAdmin(id, LoginInfo.UserType.ADMIN);
        if (integerResponseEntity.getBody() == AdminConstants.Admin.ADMIN) {
            throw new ZekeException(400, "不能修改超级管理员");
        }
        if (loginInfo.getId().equals(id)) {
            throw new ZekeException(400, "不能操作自己的账号");
        }
        if (status.equals(adminUser.getStatus())) {
            return;
        }
        if (!ObjectUtils.refrect(AdminConstants.UserStatus.class, status)) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        adminUser.setStatus(status);
        boolean i = updateById(adminUser);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
    }

    /**
     * 查询管理员列表
     *
     * @param req
     * @return
     */
    @Override
    public Page<AdminUserRes> getAdminUserPage(GetAdminPageReq req) {
        if (!StringUtils.isBlank(req.getStatus())) {
            req.setStatusStr(req.getStatus().split(","));
        }
        Page<AdminUserRes> page = req.pagePojo();
        page = getBaseMapper().getAdminUserPage(page, req);
        List<AdminUserRes> records = page.getRecords();
        List<UserToRoleRes> body = authFeignService.userRoleList().getBody();
        for (AdminUserRes res : records) {
            for (UserToRoleRes ures : body) {
                if (res.getId().equals(ures.getUserId())) {
                    res.setAdmin(ures.getAdmin());
                    res.setRoleName(ures.getRoleName());
                    res.setRoleId(ures.getId());
                    continue;
                }
            }
        }
        page.setRecords(records);
        return page;
    }

    /**
     * 运营管理员修改密码
     *
     * @param oldPwd
     * @param newPwd1
     * @param newPwd2
     */
    @Override
    public void adminUserPwd(String oldPwd, String newPwd1, String newPwd2) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.ADMIN).get();

        if (oldPwd.equals(newPwd1)){
            throw new ZekeException(400, "新密码不能与旧密码一致");
        }
        AdminUser mu = getById(loginInfo.getId());
        oldPwd = CodecUtils.md5Hex(oldPwd, mu.getSalt());
        if (!Objects.equals(oldPwd, mu.getPassword())) {
            throw new ZekeException(400, "原密码错误");
        }
        mu.setSalt(CodecUtils.generateSalt());
        mu.setPassword(CodecUtils.md5Hex(newPwd2, mu.getSalt()));
        mu.setFirstLogin(1);
        updateById(mu);
    }

    /**
     * 确认运营管理员手机号是否使用
     *
     * @param phone 手机号
     * @return
     */
    @Override
    public boolean checkPhoneUsed(String phone) {
        QueryWrapper<AdminUser> qs = new QueryWrapper<>();
        qs.lambda().ne(AdminUser::getStatus, AdminConstants.UserStatus.DEL);
        qs.lambda().eq(AdminUser::getPhone, phone);
        AdminUser mechanUser = getOne(qs);
        if (mechanUser != null) {
            return true;
        }
        return false;
    }

    /**
     * 确认运营管理员账号是否使用
     *
     * @param phone 手机号
     * @return
     */
    public boolean checkAccountUsed(String phone) {
        QueryWrapper<AdminUser> qs = new QueryWrapper<>();
        qs.lambda().ne(AdminUser::getStatus, AdminConstants.UserStatus.DEL);
        qs.lambda().eq(AdminUser::getAccount, phone);
        AdminUser mechanUser = getOne(qs);
        if (mechanUser != null) {
            return true;
        }
        return false;
    }

    /**
     * 下载系统模板文件
     *
     * @param response
     * @param type
     */
    @Override
    public void resourceDownload(HttpServletResponse response, Integer type) {
        String fileName = null;
        if (!ObjectUtils.refrect(AdminConstants.TemplateType.class, type)) {
            throw new ZekeException("模板类型错误");
        }
        switch (type) {
            case AdminConstants.TemplateType.CHDRUGS:
                fileName = "template/名老中医智能辅助诊疗（学习）系统添加中药材信息表.xlsx";
                break;
            case AdminConstants.TemplateType.CHPATENT:
                fileName = "template/名老中医智能辅助诊疗（学习）系统添加中成药信息表.xlsx";
                break;
            case AdminConstants.TemplateType.FOODMODEL:
                fileName = "template/名老中医智能辅助诊疗（学习）系统添加药食同源信息表.xlsx";
                break;
            case AdminConstants.TemplateType.CURR:
                fileName = "template/名老中医智能辅助诊疗（学习）系统添加经验方信息表.xlsx";
                break;
            case AdminConstants.TemplateType.CLASSROOM:
                fileName = "template/课堂导入模板.xlsx";
                break;
            case AdminConstants.TemplateType.DRUGS:
                fileName = "template/药品导入模板.xlsx";
                break;
            case AdminConstants.TemplateType.DRUGSWARE:
                fileName = "template/药品入库模板.xlsx";
                break;
        }
        if (fileName != null) {
            ResourceDownloadUtil.resourceDownload(response, fileName);
        }
    }

    /**
     * 获取统计用户数量
     *
     * @return
     */
    @Override
    public StatisticalUserNumRes getStatisticalUserNum() {
        return getBaseMapper().getStatisticalUserNum();
    }

    /**
     * 获取统计机构地址及医生数量
     *
     * @return
     */
    @Override
    public Map<String, List<StatisticalMechanAddrRes>> getStatisticalMechanAddr() {
        List<StatisticalMechanAddrRes> list = getBaseMapper().getStatisticalMechanAddr();
        Map<String, List<StatisticalMechanAddrRes>> res = new HashMap<>(list.size());
        for (StatisticalMechanAddrRes item : list) {
            if (!res.containsKey(item.getProvince())) {
                List<StatisticalMechanAddrRes> temp = new LinkedList<>();
                res.put(item.getProvince(), temp);
            }
            res.get(item.getProvince()).add(item);
        }
        return res;
    }

    /**
     * 查询各地区的机构数量占比
     *
     * @return
     */
    @Override
    public List<StatisticalMechanRegionRes> getStatisticalMechanRegion() {
        List<StatisticalMechanRegionRes> list = getBaseMapper().getStatisticalMechanRegion();
        list.stream().forEach(res -> {
            if (res.getAllCount() == 0 || res.getMechanCount() == 0) {
                res.setScale(0.00);
            } else {
                BigDecimal valueDecimal = new BigDecimal(res.getMechanCount() * 100.0 / res.getAllCount());
                double value = valueDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                res.setScale(value);
            }

        });
        return list;
    }

    /**
     * 统计机构开方数量及总数量
     *
     * @return
     */
    @Override
    public List<StatisticalMechanPresRes> getStatisticalMechanPres(String timeType) {
        List<StatisticalMechanPresRes> list = getBaseMapper().getStatisticalMechanPres(timeType);
        list.stream().forEach(res -> {
            if (res.getCountAll() == 0 || res.getCountMechan() == 0) {
                res.setScale(0.0);
            }
            BigDecimal valueDecimal = new BigDecimal(res.getCountMechan() * 100.0 / res.getCountAll());
            double value = valueDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            res.setScale(value);
        });
        return list;
    }

    /**
     * 查询机构类型数量占比
     *
     * @return
     */
    @Override
    public List<StatisticalMechanTypeRes> getStatisticalMechanType() {
        List<StatisticalMechanTypeRes> list = getBaseMapper().getStatisticalMechanType();
        list.stream().forEach(res -> {
            if (res.getCountAll() == 0 || res.getCountMechan() == 0) {
                res.setScale(0.0);
            }
            BigDecimal valueDecimal = new BigDecimal(res.getCountMechan() * 100.0 / res.getCountAll());
            double value = valueDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            res.setScale(value);
        });
        return list;
    }

    /**
     * 查询各个时间维度的机构处方数据
     *
     * @return
     */
    @Override
    public List<StatisticalNodeRes> getStatisticalMechanDateNode(StatisticalMechanDateNodeReq req) {
        if (req.getCount() == null) {
            req.setCount(30);
        }
        LocalDateTime qu = LocalDateTime.now();
        switch (req.getNode()) {
            case "day":
                if (req.getEndDate() != null && req.getStartDate() != null) {
                    int day = (int) (req.getEndDate().toEpochDay() - req.getStartDate().toEpochDay());
                    req.setCount(day + 1);
                    req.setStartDate(req.getEndDate());
                } else {
                    req.setStartDate(LocalDate.now());
                }
                break;
            case "month":
                if (req.getEndDate() != null && req.getStartDate() != null) {
                    int years = req.getEndDate().getYear() - req.getStartDate().getYear();
                    int month = years * 12 + (req.getEndDate().getMonthValue() - req.getStartDate().getMonthValue());
                    req.setCount(month + 1);
                    req.setStartDate(req.getEndDate());
                } else {
                    qu = DateUtils.getFirstDayOfMonth(LocalDate.now());
                    req.setStartDate(qu.toLocalDate());
                }
                break;
            case "quarter":
                if (req.getEndDate() != null && req.getStartDate() != null) {
                    req.setCount(DateUtils.getSeasonList(req.getStartDate(), req.getEndDate()).size());
                    req.setStartDate(req.getEndDate());
                } else {
                    qu = DateUtils.quarterStartTime(LocalDate.now());
                    req.setStartDate(qu.toLocalDate());
                }
                break;
            case "year":
                if (req.getEndDate() != null && req.getStartDate() != null) {
                    int years = req.getEndDate().getYear() - req.getStartDate().getYear();
                    req.setCount(years + 1);
                    req.setStartDate(req.getEndDate());
                } else {
                    qu = DateUtils.yearStartTime(LocalDate.now());
                    req.setStartDate(qu.toLocalDate());
                }
                break;
            default:
                throw new ZekeException(400, "查询节点参数错误");
        }
        List<StatisticalNodeRes> list = getBaseMapper().getStatisticalMechanDateNode(req);
        List<StatisticalNodeRes> areaList = getBaseMapper().getStatisticalMechanDateArea(req);

        int size = list.size();
        for (int i = 0; i < size; i++) {
            StatisticalNodeRes res = list.get(i);
            res.setPresNum(res.getNodeList().stream().mapToInt(StatisticalMechanDateNodeRes::getPresNum).sum());
            areaList.stream().forEach(area -> {
                if (area.getDate().equals(res.getDate())) {
                    res.setAreaNum(area.getAreaList().stream().mapToInt(StatisticalMechanDateAreaRes::getAreaNum).sum());
                    res.setAreaList(area.getAreaList());
                }
            });
            switch (req.getNode()) {
                case "day":
                    res.setDate(res.getDate().substring(5));
                    break;
                case "month":
                    String mon = res.getDate().substring(5, 7);
                    if (mon.equals("01") || i == 0) {
                        mon = res.getDate().substring(0, 4) + "年" + mon;
                    }
                    mon = mon + "月";
                    res.setDate(mon);
                    break;
                case "quarter":
                    if (res.getQu() == 1 || i == 0) {
                        res.setDate(res.getDate().substring(0, 4) + "第" + res.getQu() + "季度");
                    } else {
                        res.setDate("第" + res.getQu() + "季度");
                    }
                    break;
                default:
                    res.setDate(res.getDate().substring(0, 4));
                    break;
            }
        }
        return list;
    }

    /**
     * 获取机构选择列表
     *
     * @param req
     * @return
     */
    @Override
    public List<MechanRankSelectRes> getMechanSelect(MechanRankSelectStatisticalReq req) {
        List<MechanRankSelectRes> res = getBaseMapper().getMechanSelect(req);
        return res;
    }

    /**
     * 获取机构处方图表数据
     *
     * @param req
     * @return
     */
    @Override
    public List<MechanRankPresRes> getMechanPresDay(MechanRankPresStatisticalReq req) {
        if (!StringUtils.isBlank(req.getMechanIds())) {
            req.setMechanIdStr(req.getMechanIds().split(","));
        }
        if (!StringUtils.isBlank(req.getMechanNames())) {
            req.setMechanNameStr(req.getMechanNames().split(","));
        }
        List<MechanRankPresRes> res = getBaseMapper().getMechanPresDay(req);
        return res;
    }

    /**
     * 查询管理员类型
     *
     * @param userId
     * @return
     */
    @Override
    public Integer getAdminUserType(Integer userId) {
        QueryWrapper<AdminUser> qw = new QueryWrapper<>();
        qw.lambda().eq(AdminUser::getId, userId);
        qw.lambda().select(AdminUser::getType);
        AdminUser adminUser = getOne(qw);
        return adminUser == null ? -1 : adminUser.getType();
    }

    /**
     * 重置管理员密码
     *
     * @param adminId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetAdminUserPassword(Integer adminId) {
        QueryWrapper<AdminUser> qw = new QueryWrapper<>();
        qw.lambda().eq(AdminUser::getId, adminId);
        qw.lambda().ne(AdminUser::getStatus, AdminConstants.UserStatus.DEL);
        AdminUser adminUser = getOne(qw);
        if (adminUser == null) {
            throw new ZekeException(400, "账号不存在");
        }
        AdminUser update = new AdminUser();
        update.setId(adminId);
        update.setSalt(CodecUtils.generateSalt());
        update.setPassword(CodecUtils.md5Hex(adminUser.getPhone().substring(5), update.getSalt()));
        updateById(update);
    }
}
